/*
 * Indice.h
 *
 */

#ifndef INDICE_H_
#define INDICE_H_
#include <algorithm>
#include <cstring>
#include <vector>
#include "../IndiceArbolBMas/ElementoHoja.h"
#include "../ArchivoDeBloques/ArchivoDeBloques.h"
#include "NodoHoja.h"
#include "NodoInterno.h"
#include "ResultadoBuscar.h"
#include "../Identificadores/NodosId.h"

using namespace std;

class Indice {
public:
	Indice(string nombre, int tamBloque);
	Indice(string nombre);
	virtual ~Indice();

	ArchivoDeBloques* archivoBloques;

	/*Nodos libres*/
	std::vector<int> nodosLibres;
	int guardarNodosLibres (string nombreArch);
	int cargarNodosLibres (string nombreArch);

	/*Operaciones*/

	/*Si la clave ya se encuentra o hay error devuelve -1*/
	int alta (ElementoHoja elementoClaveValor);

	/*Si la clave no se encuentra o hay error devuelve -1*/
	int modificar (ElementoHoja elementoClaveValor);

	/*Si la clave no se encuentra o hay error devuelve -1*/
	int baja (int clave);

	/*Devuelve el numero de nodo SECUENCIAL donde se encuentra la clave o -1 si no esta.*/
	ResultadoBuscar buscar (int clave);

	/*Devuelve el elemento  donde se encuentra la clave*/
	ElementoHoja buscarElemento(int clave) ;

	int escribirNodoHoja (NodoHoja nodo);
	int escribirNodoInterno (NodoInterno nodo);
	Bloque * leerNodo (int numNodo);

	/* Recorre el arbol y devuelve todos sus elementos ordenados en un vector de elementos hojas */
	vector<ElementoHoja> recorreOrdenado();

private:
	/*Es un metodo interno usado por el metodo Buscar*/
	ResultadoBuscar buscarClaveInterno (int clave, int numeroDeNodo, int numeroDeNodoPadre);

	/*Es un metodo interno usado por el metodo Modificar*/
	int modificarInterno (NodoHoja nodo, ElementoHoja elementoClaveValor);

	/*Es un metodo interno usado por el metodo Baja*/
	int bajaInterna (NodoHoja nodo, int clave);

	/*Es un metodo interno*/
	int sobrescribirNodoHoja (NodoHoja nodo);

	/*Es un metodo interno*/
	int sobrescribirNodoInterno (NodoInterno nodo);

	/*Parte la hoja*/
	int resolverOverflowHoja (NodoHoja nodo, int numNodoPadre);

	/*Parte la raiz*/
	int resolverOverflowRaiz (NodoHoja nodo);

	/*Parte el interno*/
	int resolverOverflowInterno (NodoInterno nodo, int numNodoPadre);

	/*Parte el interno*/
	int resolverOverflowInternoRaiz(NodoInterno nodo);

	int altaEnNodoInterno (int numNodo, int clave, int numNodoSube);

	/*Obtiene el numero del nodo padre de un nodo interno*/
	int obtenerPadreDeNodoInterno (int numNodoInterno);

};

#endif /* INDICE_H_ */
